package com.zshan.clinic.common.util.json;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.TimeZone;


@Slf4j
public class JsonUtil {


    private static final ObjectMapper objectMapper = new ObjectMapper();

    static {
        // 1. 忽略未知字段，防止反序列化报错
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 2. 忽略不能被序列化的字段（如 transient、某些代理对象）
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 3. 输出格式化 JSON（调试用，可关闭）
//        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        // 4. 只序列化非 null 的字段（可选）
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 5. 日期格式 & 禁止写成时间戳
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        // 6. 忽略无法识别的 Enum 值（防止线上枚举变更出错）
        objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
        // 7. 支持单值数组反序列化为数组（如 "a" 解析成 ["a"]）
        objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
        // 9. 空字符串当 null 处理（某些前端可能传 ""）
        objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        // 10. 允许字段名无引号（非标准 JSON，视前端而定）
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        // 11. 允许特殊字符转义（如控制字符）
        objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);

        // ★★ 关键：注册 JSR-310 模块
        JavaTimeModule jsr310 = new JavaTimeModule();
        // （可选）如果你想全局固定输出/输入格式，配置序列化/反序列化器：
        DateTimeFormatter DATE     = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter DATETIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter TIME     = DateTimeFormatter.ofPattern("HH:mm:ss");
        jsr310.addSerializer(LocalDate.class,      new LocalDateSerializer(DATE));
        jsr310.addSerializer(LocalDateTime.class,  new LocalDateTimeSerializer(DATETIME));
        jsr310.addSerializer(LocalTime.class,      new LocalTimeSerializer(TIME));
        jsr310.addDeserializer(LocalDate.class,      new LocalDateDeserializer(DATE));
        jsr310.addDeserializer(LocalDateTime.class,  new LocalDateTimeDeserializer(DATETIME));
        jsr310.addDeserializer(LocalTime.class,      new LocalTimeDeserializer(TIME));
        objectMapper.registerModule(jsr310);
    }

    public static String getCode(String json) {
        try {
            return objectMapper.readTree(json).get("code").asText();
        } catch (Exception e) {
            throw new RuntimeException("解析 code 出错", e);
        }
    }

    /**
     * 对象转 JSON 字符串
     */
    public static String obj2Json(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonMappingException e) {
            log.error("对象转json发生异常",e);
        } catch (Exception e) {
            log.error("对象转json发生异常",e);
        }
        return null;
    }

    public static <T> T json2Obj(String json, TypeReference<T> typeReference) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        try {
            return objectMapper.readValue(json, typeReference);
        } catch (Exception e) {
            log.error("json转对象异常", e);
            return null;
        }
    }

    /***
     * 转换成map
     * @param json
     * @return
     */
    public static Map<String, Object> jsonToMap(String json) {
        try {
            return objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});
        } catch (JsonMappingException e) {
        } catch (Exception e) {
            log.error("json转map发生异常",e);
        }
        return null;
    }



}
